package com.hk.controller;

import com.hk.domain.entity.Data;
import com.hk.service.business.LockBusiness;
import com.hk.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

/**
 * 锁相关的坑
 * 1、静态字段属于【类】，类级别的锁才能保护
 * 2、非静态字段属于【类实例】，实例级别的锁就可以保护
 * @author: dpb
 * @date: 2022/11/29
 */
@RestController
@RequestMapping("/lock")
@Slf4j
public class LockController {


    private List<Integer> list = new ArrayList<>();


    @Autowired
    private LockBusiness lockBusiness;

    @GetMapping("/interesting")
    public R interesting() {
        new Thread(() -> lockBusiness.add()).start();
        new Thread(() -> lockBusiness.compare()).start();
        return R.ok();
    }

    @GetMapping("/wrong")
    public int wrong(@RequestParam(value = "count",defaultValue = "1000000") int count) {
        Data.reset();
        IntStream.rangeClosed(1,count).parallel().forEach(i -> new Data().wrong());
        return Data.getCount().get();
    }

    @GetMapping("/error")
    public int error() {
        long start = System.currentTimeMillis();
        IntStream.rangeClosed(1,1000).parallel().forEach(i -> {
            synchronized (this) {
                lockBusiness.slow();
                list.add(i);
            }
        });

        long time = System.currentTimeMillis() - start;
        log.info("time:{}", time);
        return list.size();
    }

    @GetMapping("/right")
    public int right() {
        long start = System.currentTimeMillis();
        IntStream.rangeClosed(1,1000).parallel().forEach(i -> {
            lockBusiness.slow();
            synchronized (this) {
                list.add(i);
            }
        });

        long time = System.currentTimeMillis() - start;
        log.info("time:{}", time);
        return list.size();
    }

}
